package com.xueyi.workflow.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xueyi.common.core.web.page.TableDataInfo;
import com.xueyi.workflow.domain.dto.WfProcessInstanceDto;
import com.xueyi.workflow.domain.dto.StartProcessRequest;
import com.xueyi.workflow.domain.query.WfProcessInstanceQuery;
import com.xueyi.workflow.manager.IWfProcessInstanceManager;
import com.xueyi.workflow.service.IWfProcessInstanceService;
import com.xueyi.workflow.correlate.WfProcessInstanceCorrelate;
import com.xueyi.common.web.entity.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.xueyi.workflow.service.IWfProcessVersionService;
import com.xueyi.workflow.domain.dto.WfProcessVersionDto;
import com.xueyi.workflow.service.FormDataService;
import com.xueyi.workflow.domain.dto.FormDataDto;
import com.xueyi.common.security.utils.SecurityUtils;
import com.xueyi.common.core.utils.page.PageUtil;
import com.github.pagehelper.PageInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.xueyi.workflow.domain.dto.ProcessFormBindDto;
import com.xueyi.workflow.domain.query.ProcessFormBindQuery;
import com.xueyi.workflow.service.ProcessFormBindService;

/**
 * 流程实例Service业务层处理
 *
 * @author xueyi
 * @date 2024-07-03
 */
@Slf4j
@Service
public class WfProcessInstanceServiceImpl extends BaseServiceImpl<WfProcessInstanceQuery, WfProcessInstanceDto, WfProcessInstanceCorrelate, IWfProcessInstanceManager> implements IWfProcessInstanceService {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private IWfProcessVersionService wfProcessVersionService;

    @Autowired
    private FormDataService formDataService;

    @Autowired
    private ProcessFormBindService processFormBindService;

    /**
     * 查询流程实例分页列表
     */
    @Override
    public TableDataInfo<WfProcessInstanceDto> queryPageList(WfProcessInstanceQuery query) {
        // 添加调试信息
        log.info("查询流程实例列表，当前用户租户ID: {}", SecurityUtils.getEnterpriseId());
        log.info("查询条件: {}", query);

        // 获取当前登录用户名
        String currentUsername = SecurityUtils.getUserName();
        log.info("当前登录用户: {}", currentUsername);

        // 设置查询条件：只查询当前用户发起的流程
        query.setInitiator(currentUsername);

        // 使用分页机制
        PageUtil.startPage();
        List<WfProcessInstanceDto> list = selectList(query);

        log.info("查询结果数量: {}", list.size());
        if (list.size() > 0) {
            log.info("第一条数据: {}", list.get(0));
        }

        // 处理数据字段映射
        list.forEach(this::processProcessInstanceData);

        // 使用框架的分页响应方法
        TableDataInfo<WfProcessInstanceDto> result = new TableDataInfo<>();
        result.setItems(list);
        result.setTotal(new PageInfo<>(list).getTotal());
        return result;
    }

    /**
     * 处理流程实例数据，补充缺失字段
     */
    private void processProcessInstanceData(WfProcessInstanceDto dto) {
        // 处理startTime数组格式转换为标准日期时间
        if (dto.getStartTime() == null && dto.getCreateTime() != null) {
            dto.setStartTime(dto.getCreateTime());
        }

        // 如果没有endTime，设置为null
        if (dto.getEndTime() == null) {
            dto.setEndTime(null);
        }

        // 计算持续时间（如果流程已完成）
        if ("COMPLETED".equals(dto.getStatus()) && dto.getStartTime() != null && dto.getEndTime() != null) {
            calculateDuration(dto);
        } else {
            dto.setDuration(null);
        }

        // 设置当前节点信息（从assigneeConfig中解析）
        if (dto.getAssigneeConfig() != null && !dto.getAssigneeConfig().isEmpty()) {
            try {
                // 解析assigneeConfig获取当前节点名称
                String currentTask = parseCurrentTaskFromAssigneeConfig(dto.getAssigneeConfig());
                dto.setCurrentTask(currentTask);
            } catch (Exception e) {
                log.warn("解析assigneeConfig失败: {}", e.getMessage());
                dto.setCurrentTask("进行中");
            }
        } else {
            dto.setCurrentTask("进行中");
        }
    }

    /**
     * 从assigneeConfig中解析当前节点名称
     */
    private String parseCurrentTaskFromAssigneeConfig(String assigneeConfig) {
        try {
            if (assigneeConfig == null || assigneeConfig.isEmpty()) {
                return "进行中";
            }

            // 尝试解析JSON格式的assigneeConfig
            JsonNode configNode = objectMapper.readTree(assigneeConfig);
            if (configNode.isArray() && configNode.size() > 0) {
                // 获取第一个节点（通常是当前节点）
                JsonNode firstNode = configNode.get(0);
                if (firstNode.has("name")) {
                    return firstNode.get("name").asText();
                }
            }

            return "进行中";
        } catch (Exception e) {
            log.warn("解析assigneeConfig失败: {}", e.getMessage());
            return "进行中";
        }
    }

    /**
     * 查询流程实例详情
     */
    @Override
    public WfProcessInstanceDto getProcessInstanceDetail(Long id) {
        return selectById(id);
    }

    /**
     * 发起流程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WfProcessInstanceDto startProcess(StartProcessRequest request) {
        try {
            log.info("开始发起流程，请求参数: processId={}", request.getProcessId());

            // 验证必传参数
            if (request.getProcessId() == null || request.getProcessId().trim().isEmpty()) {
                throw new RuntimeException("processId不能为空");
            }

            if (request.getFormData() == null || request.getFormData().isEmpty()) {
                throw new RuntimeException("表单数据不能为空");
            }

            // 根据processId查询流程信息
            WfProcessVersionDto versionInfo = null;
            String processKey = null;
            Long processId = null;

            try {
                processId = Long.parseLong(request.getProcessId());
                // 获取最新版本
                Integer processVersion = wfProcessVersionService.getLatestVersion(request.getProcessId());
                versionInfo = wfProcessVersionService.getProcessVersion(request.getProcessId(), processVersion);
                processKey = versionInfo.getProcessKey();
                log.info("通过processId查询到流程信息: processId={}, processKey={}, version={}",
                    processId, processKey, processVersion);
            } catch (NumberFormatException e) {
                throw new RuntimeException("processId格式错误，应为数字: " + request.getProcessId());
            }

            if (versionInfo == null) {
                throw new RuntimeException("未找到流程信息，processId: " + processId);
            }

            log.info("成功获取流程版本信息: versionId={}, processKey={}, processName={}, version={}",
                versionInfo.getId(), versionInfo.getProcessKey(), versionInfo.getProcessName(), versionInfo.getVersion());

            // 生成业务Key（如果未传递）
            String businessKey = request.getBusinessKey();
            if (businessKey == null || businessKey.trim().isEmpty()) {
                businessKey = "BUSINESS_" + System.currentTimeMillis();
                log.info("自动生成业务Key: {}", businessKey);
            }

            // 创建流程实例
            WfProcessInstanceDto instance = new WfProcessInstanceDto();
            instance.setProcessId(processId);
            instance.setProcessKey(processKey);
            instance.setProcessName(versionInfo.getProcessName());
            instance.setProcessVersion(versionInfo.getVersion());
            instance.setBusinessKey(businessKey);
            instance.setInitiator("admin"); // TODO: 获取当前用户
            instance.setStatus("RUNNING");
            instance.setStartTime(LocalDateTime.now());
            instance.setCreateTime(LocalDateTime.now());
            instance.setUpdateTime(LocalDateTime.now());

            // 设置表单数据
            instance.setFormData(objectMapper.writeValueAsString(request.getFormData()));
            log.info("表单数据已保存到流程实例表");

            // 设置人员配置（如果传递了则使用，否则使用流程配置中的默认配置）
            if (request.getAssigneeConfig() != null && !request.getAssigneeConfig().isEmpty()) {
                instance.setAssigneeConfig(objectMapper.writeValueAsString(request.getAssigneeConfig()));
                log.info("使用前端传递的人员配置，配置数量: {}", request.getAssigneeConfig().size());
            } else {
                // 使用流程配置中的人员配置
                String defaultAssigneeConfig = getDefaultAssigneeConfig(versionInfo);
                if (defaultAssigneeConfig != null) {
                    instance.setAssigneeConfig(defaultAssigneeConfig);
                    log.info("前端未传递人员配置，使用流程版本中的默认人员配置");
                } else {
                    log.warn("前端未传递人员配置，且流程版本中也没有人员配置");
                }
            }

            // 设置流程变量（只包含自定义变量，不包含重复数据）
            Map<String, Object> customVariables = new HashMap<>();
            if (request.getVariables() != null) {
                // 过滤掉formData和assigneeConfig，避免重复
                request.getVariables().forEach((key, value) -> {
                    if (!"formData".equals(key) && !"assigneeConfig".equals(key)) {
                        customVariables.put(key, value);
                    }
                });
            }

            if (!customVariables.isEmpty()) {
                instance.setVariables(objectMapper.writeValueAsString(customVariables));
                log.info("设置自定义流程变量: {}", customVariables);
            }

            // 生成流程实例ID
            instance.setProcessInstanceId("PI_" + UUID.randomUUID().toString().replace("-", ""));

            // 保存流程实例到数据库
            int result = insert(instance);
            if (result <= 0) {
                throw new RuntimeException("流程实例创建失败");
            }

            log.info("流程实例创建成功，ID: {}, 流程Key: {}, 业务Key: {}, 版本: {}, 流程版本ID: {}",
                instance.getId(), instance.getProcessKey(), instance.getBusinessKey(), instance.getProcessVersion(), versionInfo.getId());

            // 调用Flowable引擎启动流程实例
            try {
                Map<String, Object> variables = new HashMap<>();

                // 添加表单数据到流程变量
                variables.put("formData", request.getFormData());

                // 添加人员配置到流程变量
                if (request.getAssigneeConfig() != null && !request.getAssigneeConfig().isEmpty()) {
                    variables.put("assigneeConfig", request.getAssigneeConfig());
                    log.info("流程变量中使用前端传递的人员配置，配置数量: {}", request.getAssigneeConfig().size());
                } else {
                    // 使用默认人员配置
                    String defaultConfig = getDefaultAssigneeConfig(versionInfo);
                    if (defaultConfig != null) {
                        try {
                            List<Map<String, Object>> defaultAssigneeConfig = objectMapper.readValue(defaultConfig,
                                new TypeReference<List<Map<String, Object>>>() {});
                            variables.put("assigneeConfig", defaultAssigneeConfig);
                            log.info("流程变量中使用流程版本中的默认人员配置");
                        } catch (Exception e) {
                            log.warn("解析默认人员配置失败: {}", e.getMessage());
                        }
                    } else {
                        log.warn("流程变量中未设置人员配置，因为前端未传递且流程版本中也没有配置");
                    }
                }

                // 添加自定义变量
                variables.putAll(customVariables);

                // 关键：添加流程版本ID到流程变量，用于后续获取流程图
                variables.put("processVersionId", versionInfo.getId());
                variables.put("processVersion", versionInfo.getVersion());
                variables.put("processKey", versionInfo.getProcessKey());

                log.info("设置流程变量 - processVersionId: {}, processVersion: {}, processKey: {}",
                    versionInfo.getId(), versionInfo.getVersion(), versionInfo.getProcessKey());

                // 启动Flowable流程实例
                ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
                    processKey,
                    businessKey,
                    variables
                );

                // 更新流程实例ID
                instance.setProcessInstanceId(processInstance.getId());
                update(instance);

                log.info("Flowable流程实例启动成功，ProcessInstanceId: {}", processInstance.getId());

                // 保存表单数据到wf_form_data表（作为权威存储）
                try {
                    // 查询流程-表单绑定信息
                    Long formId = getFormIdFromProcessBind(processId);

                    FormDataDto formDataDto = new FormDataDto();
                    formDataDto.setProcessInstanceId(processInstance.getId());
                    formDataDto.setProcessId(String.valueOf(processId)); // 转换为String类型
                    formDataDto.setFormId(formId != null ? String.valueOf(formId) : null); // 从流程-表单绑定获取formId
                    formDataDto.setFormData(objectMapper.writeValueAsString(request.getFormData()));
                    formDataDto.setCreateBy(1L); // TODO: 获取当前用户ID
                    formDataDto.setCreateTime(LocalDateTime.now());
                    formDataDto.setUpdateTime(LocalDateTime.now());

                    formDataService.insert(formDataDto);
                    log.info("表单数据保存到wf_form_data表成功，ProcessInstanceId: {}, FormId: {}",
                        processInstance.getId(), formId);

                    // 同时更新流程实例表中的form_data字段（作为缓存）
                    instance.setFormData(objectMapper.writeValueAsString(request.getFormData()));
                    update(instance);
                    log.info("表单数据更新到流程实例表成功，ProcessInstanceId: {}", processInstance.getId());

                } catch (Exception e) {
                    log.error("保存表单数据失败", e);
                    // 不抛出异常，继续执行
                }

                return instance;

            } catch (Exception e) {
                log.error("启动Flowable流程实例失败", e);
                // 删除已创建的流程实例记录
                deleteById(instance.getId());
                throw new RuntimeException("启动流程实例失败: " + e.getMessage());
            }

        } catch (Exception e) {
            log.error("发起流程失败", e);
            throw new RuntimeException("发起流程失败: " + e.getMessage());
        }
    }

    /**
     * 撤销流程实例
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelProcessInstance(String id, String reason) {
        try {
            // 通过processInstanceId查找记录
            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(id);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                throw new RuntimeException("流程实例不存在");
            }

            WfProcessInstanceDto dto = instances.get(0);

            // 先调用Flowable API终止流程实例，这会自动清理相关任务
            try {
                runtimeService.deleteProcessInstance(id, reason);
                log.info("Flowable流程实例 {} 已终止，原因: {}", id, reason);
            } catch (Exception e) {
                log.warn("Flowable流程实例终止失败，可能实例已不存在: {}", e.getMessage());
                // 继续执行，更新数据库状态
            }

            // 更新状态为已取消
            dto.setStatus("TERMINATED");
            dto.setRemark(reason);
            dto.setUpdateTime(LocalDateTime.now());

            int result = update(dto);
            return result > 0;
        } catch (Exception e) {
            log.error("撤销流程实例失败: {}", e.getMessage(), e);
            throw new RuntimeException("撤销流程实例失败: " + e.getMessage());
        }
    }

    /**
     * 暂停流程实例
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean suspendProcessInstance(String id) {
        // 通过processInstanceId查找记录
        WfProcessInstanceQuery query = new WfProcessInstanceQuery();
        query.setProcessInstanceId(id);
        List<WfProcessInstanceDto> instances = selectList(query);

        if (instances == null || instances.isEmpty()) {
            throw new RuntimeException("流程实例不存在");
        }

        WfProcessInstanceDto dto = instances.get(0);

        // 更新状态为已暂停
        dto.setStatus("SUSPENDED");
        dto.setUpdateTime(LocalDateTime.now());

        int result = update(dto);
        return result > 0;
    }

    /**
     * 恢复流程实例
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean resumeProcessInstance(String id) {
        // 通过processInstanceId查找记录
        WfProcessInstanceQuery query = new WfProcessInstanceQuery();
        query.setProcessInstanceId(id);
        List<WfProcessInstanceDto> instances = selectList(query);

        if (instances == null || instances.isEmpty()) {
            throw new RuntimeException("流程实例不存在");
        }

        WfProcessInstanceDto dto = instances.get(0);

        // 更新状态为运行中
        dto.setStatus("RUNNING");
        dto.setUpdateTime(LocalDateTime.now());

        int result = update(dto);
        return result > 0;
    }

    /**
     * 查询流程历史列表
     */
    @Override
    public TableDataInfo<WfProcessInstanceDto> getProcessHistoryList(WfProcessInstanceQuery query) {
       // 使用分页机制
        PageUtil.startPage();
        List<WfProcessInstanceDto> list = selectList(query);

        // 处理数据字段映射
        list.forEach(this::processProcessInstanceData);

        TableDataInfo<WfProcessInstanceDto> result = new TableDataInfo<>();
        result.setItems(list);
        result.setTotal(new PageInfo<>(list).getTotal());
        return result;
    }

    /**
     * 计算流程实例的持续时间
     */
    private void calculateDuration(WfProcessInstanceDto dto) {
        if (dto.getStartTime() != null && dto.getEndTime() != null) {
            long duration = java.time.Duration.between(dto.getStartTime(), dto.getEndTime()).toMillis();
            dto.setDuration(duration);
            log.debug("流程实例 {} 持续时间计算完成: {} 毫秒", dto.getProcessInstanceId(), duration);
        } else {
            log.warn("流程实例 {} 缺少开始时间或结束时间，无法计算持续时间", dto.getProcessInstanceId());
        }
    }

    /**
     * 获取流程配置中的人员配置
     */
    private String getDefaultAssigneeConfig(WfProcessVersionDto versionInfo) {
        try {
            if (versionInfo == null || versionInfo.getAssigneeConfig() == null || versionInfo.getAssigneeConfig().isEmpty()) {
                return null;
            }
            // 将List<Map<String, Object>>转换为JSON字符串
            return objectMapper.writeValueAsString(versionInfo.getAssigneeConfig());
        } catch (Exception e) {
            log.warn("获取流程配置中的人员配置失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 获取流程绑定的表单ID
     */
    private Long getFormIdFromProcessBind(Long processId) {
        try {
            // 查询流程-表单绑定信息
            ProcessFormBindQuery query = new ProcessFormBindQuery();
            query.setProcessId(processId.toString());
            List<ProcessFormBindDto> bindList = processFormBindService.selectList(query);

            if (bindList != null && !bindList.isEmpty()) {
                // 取第一个绑定记录的表单ID
                Long formId = bindList.get(0).getFormId();
                log.info("获取到流程 {} 绑定的表单ID: {}", processId, formId);
                return formId;
            } else {
                log.warn("流程 {} 未绑定表单", processId);
                return null;
            }
        } catch (Exception e) {
            log.warn("获取流程绑定的表单ID失败，processId: {}, 原因: {}", processId, e.getMessage());
            return null;
        }
    }

    /**
     * 更新流程实例状态为已完成
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatusToCompleted(String processInstanceId) {
        try {
            log.info("开始更新流程实例 {} 状态为已完成", processInstanceId);

            // 通过processInstanceId查找记录
            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(processInstanceId);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                log.warn("流程实例不存在，processInstanceId: {}", processInstanceId);
                return false;
            }

            WfProcessInstanceDto dto = instances.get(0);

            // 更新状态为已完成
            dto.setStatus("COMPLETED");
            dto.setEndTime(LocalDateTime.now());
            dto.setUpdateTime(LocalDateTime.now());

            // 计算持续时间
            calculateDuration(dto);

            int result = update(dto);
            boolean success = result > 0;

            if (success) {
                log.info("流程实例 {} 状态更新成功，已标记为 COMPLETED", processInstanceId);
            } else {
                log.warn("流程实例 {} 状态更新失败", processInstanceId);
            }

            return success;

        } catch (Exception e) {
            log.error("更新流程实例状态失败，processInstanceId: {}", processInstanceId, e);
            return false;
        }
    }

    /**
     * 更新流程实例状态为已暂停
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatusToSuspended(String processInstanceId, String reason) {
        try {
            log.info("开始更新流程实例 {} 状态为已暂停，原因: {}", processInstanceId, reason);

            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(processInstanceId);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                log.warn("流程实例不存在，processInstanceId: {}", processInstanceId);
                return false;
            }

            WfProcessInstanceDto dto = instances.get(0);
            dto.setStatus("SUSPENDED");
            dto.setRemark(reason);
            dto.setUpdateTime(LocalDateTime.now());

            int result = update(dto);
            boolean success = result > 0;

            if (success) {
                log.info("流程实例 {} 状态更新成功，已标记为 SUSPENDED", processInstanceId);
            } else {
                log.warn("流程实例 {} 状态更新失败", processInstanceId);
            }

            return success;

        } catch (Exception e) {
            log.error("更新流程实例状态为已暂停失败，processInstanceId: {}", processInstanceId, e);
            return false;
        }
    }

    /**
     * 更新流程实例状态为运行中
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatusToRunning(String processInstanceId) {
        try {
            log.info("开始更新流程实例 {} 状态为运行中", processInstanceId);

            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(processInstanceId);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                log.warn("流程实例不存在，processInstanceId: {}", processInstanceId);
                return false;
            }

            WfProcessInstanceDto dto = instances.get(0);
            dto.setStatus("RUNNING");
            dto.setUpdateTime(LocalDateTime.now());

            int result = update(dto);
            boolean success = result > 0;

            if (success) {
                log.info("流程实例 {} 状态更新成功，已标记为 RUNNING", processInstanceId);
            } else {
                log.warn("流程实例 {} 状态更新失败", processInstanceId);
            }

            return success;

        } catch (Exception e) {
            log.error("更新流程实例状态为运行中失败，processInstanceId: {}", processInstanceId, e);
            return false;
        }
    }

    /**
     * 更新流程实例状态为已终止
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatusToTerminated(String processInstanceId, String reason) {
        try {
            log.info("开始更新流程实例 {} 状态为已终止，原因: {}", processInstanceId, reason);

            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(processInstanceId);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                log.warn("流程实例不存在，processInstanceId: {}", processInstanceId);
                return false;
            }

            WfProcessInstanceDto dto = instances.get(0);
            dto.setStatus("TERMINATED");
            dto.setRemark(reason);
            dto.setEndTime(LocalDateTime.now());
            dto.setUpdateTime(LocalDateTime.now());

            // 计算持续时间
            calculateDuration(dto);

            int result = update(dto);
            boolean success = result > 0;

            if (success) {
                log.info("流程实例 {} 状态更新成功，已标记为 TERMINATED", processInstanceId);
            } else {
                log.warn("流程实例 {} 状态更新失败", processInstanceId);
            }

            return success;

        } catch (Exception e) {
            log.error("更新流程实例状态为已终止失败，processInstanceId: {}", processInstanceId, e);
            return false;
        }
    }

    /**
     * 更新流程实例状态为错误
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatusToError(String processInstanceId, String reason) {
        try {
            log.info("开始更新流程实例 {} 状态为错误，原因: {}", processInstanceId, reason);

            WfProcessInstanceQuery query = new WfProcessInstanceQuery();
            query.setProcessInstanceId(processInstanceId);
            List<WfProcessInstanceDto> instances = selectList(query);

            if (instances == null || instances.isEmpty()) {
                log.warn("流程实例不存在，processInstanceId: {}", processInstanceId);
                return false;
            }

            WfProcessInstanceDto dto = instances.get(0);
            dto.setStatus("ERROR");
            dto.setRemark(reason);
            dto.setEndTime(LocalDateTime.now());
            dto.setUpdateTime(LocalDateTime.now());

            // 计算持续时间
            calculateDuration(dto);

            int result = update(dto);
            boolean success = result > 0;

            if (success) {
                log.info("流程实例 {} 状态更新成功，已标记为 ERROR", processInstanceId);
            } else {
                log.warn("流程实例 {} 状态更新失败", processInstanceId);
            }

            return success;

        } catch (Exception e) {
            log.error("更新流程实例状态为错误失败，processInstanceId: {}", processInstanceId, e);
            return false;
        }
    }
}
